﻿using System;
using System.Text.RegularExpressions;
using CodeKicker.BBCode;

namespace Smarly.Forum.Bussines.Parsing
{
	public static class BbCodeExtentions
	{
		public static string ToHtml(this string bb)
		{
			if (bb == null) return null;
			var parser = new BBCodeParser(new[]
                {
                    new BBTag("ul", "<ul${id}>", "</ul>", new BBAttribute("id", "", GetIdAttributeValue, HtmlEncodingMode.UnsafeDontEncode), new BBAttribute("id", "id", GetIdAttributeValue, HtmlEncodingMode.UnsafeDontEncode)), 
                    new BBTag("ol", "<ol${id}>", "</ol>", new BBAttribute("id", "", GetIdAttributeValue, HtmlEncodingMode.UnsafeDontEncode), new BBAttribute("id", "id", GetIdAttributeValue, HtmlEncodingMode.UnsafeDontEncode)), 
                    new BBTag("p", "<p${id}>", "</p>", new BBAttribute("id", "", GetIdAttributeValue, HtmlEncodingMode.UnsafeDontEncode), new BBAttribute("id", "id", GetIdAttributeValue, HtmlEncodingMode.UnsafeDontEncode)), 
                    new BBTag("div", "<div${id}>", "</div>", new BBAttribute("id", "", GetIdAttributeValue, HtmlEncodingMode.UnsafeDontEncode), new BBAttribute("id", "id", GetIdAttributeValue, HtmlEncodingMode.UnsafeDontEncode)), 
                    new BBTag("h1", "<h1${id}>", "</h1>", new BBAttribute("id", "", GetIdAttributeValue, HtmlEncodingMode.UnsafeDontEncode), new BBAttribute("id", "id", GetIdAttributeValue, HtmlEncodingMode.UnsafeDontEncode)), 
                    new BBTag("h2", "<h2${id}>", "</h2>", new BBAttribute("id", "", GetIdAttributeValue, HtmlEncodingMode.UnsafeDontEncode), new BBAttribute("id", "id", GetIdAttributeValue, HtmlEncodingMode.UnsafeDontEncode)), 
                    new BBTag("h3", "<h3${id}>", "</h3>", new BBAttribute("id", "", GetIdAttributeValue, HtmlEncodingMode.UnsafeDontEncode), new BBAttribute("id", "id", GetIdAttributeValue, HtmlEncodingMode.UnsafeDontEncode)), 
                    new BBTag("h4", "<h4${id}>", "</h4>", new BBAttribute("id", "", GetIdAttributeValue, HtmlEncodingMode.UnsafeDontEncode), new BBAttribute("id", "id", GetIdAttributeValue, HtmlEncodingMode.UnsafeDontEncode)), 
                    new BBTag("h5", "<h5${id}>", "</h5>", new BBAttribute("id", "", GetIdAttributeValue, HtmlEncodingMode.UnsafeDontEncode), new BBAttribute("id", "id", GetIdAttributeValue, HtmlEncodingMode.UnsafeDontEncode)), 
                    new BBTag("h6", "<h6${id}>", "</h6>", new BBAttribute("id", "", GetIdAttributeValue, HtmlEncodingMode.UnsafeDontEncode), new BBAttribute("id", "id", GetIdAttributeValue, HtmlEncodingMode.UnsafeDontEncode)), 
                    new BBTag("li", "<li>", "</li>"), 
                    new BBTag("blockquote", "<blockquote>", "</blockquote>"), 
                    new BBTag("b", "<strong>", "</strong>"), 
                    new BBTag("thead", "<thead>", "</thead>"), 
                    new BBTag("tbody", "<tbody>", "</tbody>"), 
                    new BBTag("tr", "<tr>", "</tr>"), 
                    new BBTag("td", "<td>", "</td>"), 
                    new BBTag("pre", "<pre><code class=\"${class}\">", "</code></pre>", new BBAttribute("class", "")){GreedyAttributeProcessing = true}, 
                    new BBTag("table", "<table class=\"${class}\">", "</table>", new BBAttribute("class", "")){GreedyAttributeProcessing = true}, 
                    new BBTag("i", "<em>", "</em>"), 
                    new BBTag("u", "<span style=\"text-decoration:underline;\">", "</span>"), 
                    new BBTag("code", "<code>", "</code>"), 
                    new BBTag("img", "<img src=\"${url}\"/>", "", true, false, new BBAttribute("url", "")){GreedyAttributeProcessing = true}, 
                    new BBTag("br", "<br/>", "", true, false), 
                    new BBTag("quote", "<blockquote>", "</blockquote>"), 
                    new BBTag("url", "<a ${href>", "</a>", new BBAttribute("href", "", GetUrlTagHrefAttributeValue), new BBAttribute("href", "href", GetUrlTagHrefAttributeValue)), 
                });
			return parser.ParseSyntaxTree(bb).ToHtml();
		}


		public static string ToBbCode(this string html)
		{
			if (string.IsNullOrWhiteSpace(html))
				return string.Empty;

			html = Regex.Replace(html, @"<br(.*?)/>", "\n", RegexOptions.IgnoreCase);

			html = Regex.Replace(html, @"<HR[^>]*>", "[hr]", RegexOptions.IgnoreCase);

			html = Regex.Replace(html, @"<LI>", "[li]", RegexOptions.IgnoreCase);
			html = Regex.Replace(html, @"<\/li>", "[/li]", RegexOptions.IgnoreCase);

			html = Regex.Replace(html, @"<P>", "[p]", RegexOptions.IgnoreCase);
			html = Regex.Replace(html, @"<\/P>", "[/p]", RegexOptions.IgnoreCase);

			html = Regex.Replace(html, @"<STRONG>", "[b]", RegexOptions.IgnoreCase);
			html = Regex.Replace(html, @"<\/STRONG>", "[/b]", RegexOptions.IgnoreCase);

			html = Regex.Replace(html, @"<u>", "[u]", RegexOptions.IgnoreCase);
			html = Regex.Replace(html, @"<\/u>", "[/u]", RegexOptions.IgnoreCase);

			html = Regex.Replace(html, @"<em>", "[i]", RegexOptions.IgnoreCase);
			html = Regex.Replace(html, @"<\/em>", "[/i]", RegexOptions.IgnoreCase);

			html = Regex.Replace(html, @"<table class=""", "[table=", RegexOptions.IgnoreCase);
			html = Regex.Replace(html, @"<table>", "[table]", RegexOptions.IgnoreCase);
			html = Regex.Replace(html, @"<\/table>", "[/table]", RegexOptions.IgnoreCase);

			html = Regex.Replace(html, @"<blockquote>", "[blockquote]", RegexOptions.IgnoreCase);
			html = Regex.Replace(html, @"<\/blockquote>", "[/blockquote]", RegexOptions.IgnoreCase);

			html = Regex.Replace(html, @"<thead>", "[thead]", RegexOptions.IgnoreCase);
			html = Regex.Replace(html, @"<\/thead>", "[/thead]", RegexOptions.IgnoreCase);

			html = Regex.Replace(html, @"<tbody>", "[tbody]", RegexOptions.IgnoreCase);
			html = Regex.Replace(html, @"<\/tbody>", "[/tbody]", RegexOptions.IgnoreCase);

			html = Regex.Replace(html, @"<tr>", "[tr]", RegexOptions.IgnoreCase);
			html = Regex.Replace(html, @"<\/tr>", "[/tr]", RegexOptions.IgnoreCase);

			html = Regex.Replace(html, @"<td>", "[td]", RegexOptions.IgnoreCase);
			html = Regex.Replace(html, @"<\/td>", "[/td]", RegexOptions.IgnoreCase);

			html = Regex.Replace(html, @"<img src=""", "[img=", RegexOptions.IgnoreCase);

			html = Regex.Replace(html, @"<pre><code class=""", "[pre=", RegexOptions.IgnoreCase);
			html = Regex.Replace(html, @"<\/code><\/pre>", "[/pre]", RegexOptions.IgnoreCase);

			html = Regex.Replace(html, @"<code>", "[code]", RegexOptions.IgnoreCase);
			html = Regex.Replace(html, @"<\/code>", "[/code]", RegexOptions.IgnoreCase);

			html = Regex.Replace(html, @"<pre>", "[pre]", RegexOptions.IgnoreCase);
			html = Regex.Replace(html, @"<\/pre>", "[/pre]", RegexOptions.IgnoreCase);

			html = Regex.Replace(html, @"<sup>", "[sup]", RegexOptions.IgnoreCase);
			html = Regex.Replace(html, @"<\/sup>", "[/sup]", RegexOptions.IgnoreCase);

			html = Regex.Replace(html, @"<sub>", "[sub]", RegexOptions.IgnoreCase);
			html = Regex.Replace(html, @"<\/sub>", "[/sub]", RegexOptions.IgnoreCase);

			html = Regex.Replace(html, @"<STRIKE>", "[strike]", RegexOptions.IgnoreCase);
			html = Regex.Replace(html, @"<\/STRIKE>", "[/strike]", RegexOptions.IgnoreCase);

			html = Regex.Replace(html, @"<UL ID=""", "[ul=", RegexOptions.IgnoreCase);
			html = Regex.Replace(html, @"<UL[^>]*>", "[ul]", RegexOptions.IgnoreCase);
			html = Regex.Replace(html, @"<\/UL>", "[/ul]", RegexOptions.IgnoreCase);

			html = Regex.Replace(html, @"<OL ID=""", "[ol=", RegexOptions.IgnoreCase);
			html = Regex.Replace(html, @"<OL[^>]*>", "[ol]", RegexOptions.IgnoreCase);
			html = Regex.Replace(html, @"<\/OL>", "[/ol]", RegexOptions.IgnoreCase);

			html = Regex.Replace(html, @"<h1 ID=""", "[h1=", RegexOptions.IgnoreCase);
			html = Regex.Replace(html, @"<h1>", "[h1]", RegexOptions.IgnoreCase);
			html = Regex.Replace(html, @"<\/h1>", "[/h1]", RegexOptions.IgnoreCase);

			html = Regex.Replace(html, @"<h2 ID=""", "[h2=", RegexOptions.IgnoreCase);
			html = Regex.Replace(html, @"<h2>", "[h2]", RegexOptions.IgnoreCase);
			html = Regex.Replace(html, @"<\/h2>", "[/h2]", RegexOptions.IgnoreCase);

			html = Regex.Replace(html, @"<h3 ID=""", "[h3=", RegexOptions.IgnoreCase);
			html = Regex.Replace(html, @"<h3>", "[h3]", RegexOptions.IgnoreCase);
			html = Regex.Replace(html, @"<\/h3>", "[/h3]", RegexOptions.IgnoreCase);

			html = Regex.Replace(html, @"<h4 ID=""", "[h4=", RegexOptions.IgnoreCase);
			html = Regex.Replace(html, @"<h4>", "[h4]", RegexOptions.IgnoreCase);
			html = Regex.Replace(html, @"<\/h4>", "[/h4]", RegexOptions.IgnoreCase);

			html = Regex.Replace(html, @"<h5 ID=""", "[h5=", RegexOptions.IgnoreCase);
			html = Regex.Replace(html, @"<h5>", "[h5]", RegexOptions.IgnoreCase);
			html = Regex.Replace(html, @"<\/h5>", "[/h5]", RegexOptions.IgnoreCase);

			html = Regex.Replace(html, @"<h6 ID=""", "[h6=", RegexOptions.IgnoreCase);
			html = Regex.Replace(html, @"<h6>", "[h6]", RegexOptions.IgnoreCase);
			html = Regex.Replace(html, @"<\/h6>", "[/h6]", RegexOptions.IgnoreCase);

			html = Regex.Replace(html, @"<A REL=""NOFOLLOW"" HREF=""", "[url=", RegexOptions.IgnoreCase);
			html = Regex.Replace(html, @"<A REL=""NOFOLLOW"" HREF='", "[url=", RegexOptions.IgnoreCase);

			html = Regex.Replace(html, @"<A HREF=""", "[url=", RegexOptions.IgnoreCase);
			html = Regex.Replace(html, @"<A HREF='", "[url=", RegexOptions.IgnoreCase);
			html = Regex.Replace(html, @"<\/A>", "[/url]", RegexOptions.IgnoreCase);

			html = Regex.Replace(html, @"<P ID=""", "[p=", RegexOptions.IgnoreCase);
			html = Regex.Replace(html, @"<P>", "[p]", RegexOptions.IgnoreCase);
			html = Regex.Replace(html, @"<\/P>", "[/p]", RegexOptions.IgnoreCase);

			html = Regex.Replace(html, @"<DIV ID=""", "[div=", RegexOptions.IgnoreCase);
			html = Regex.Replace(html, @"<DIV>", "[div]", RegexOptions.IgnoreCase);
			html = Regex.Replace(html, @"<\/DIV>", "[/div]", RegexOptions.IgnoreCase);

			html = Regex.Replace(html, @""">", "]", RegexOptions.IgnoreCase);
			html = Regex.Replace(html, @"=]", "]", RegexOptions.IgnoreCase);
			html = Regex.Replace(html, @"""(\s)*/>", "]", RegexOptions.IgnoreCase);


			return html;
		}

		static string GetUrlTagHrefAttributeValue(IAttributeRenderingContext attributeRenderingContext)
		{
			string result = "";

			if (!string.IsNullOrWhiteSpace(attributeRenderingContext.AttributeValue))
			{
				result = Regex.Replace(attributeRenderingContext.AttributeValue, @"javascript", "", RegexOptions.IgnoreCase);

				if (result.StartsWith("/") || result.StartsWith(@"\"))
				{
					result = string.Format("href=\"{0}\"", result);
				}
				else
				{
					try
					{
						Uri uri = new Uri(result);
						if (uri.Host.EndsWith("smarly.net"))
						{
							result = string.Format("href=\"{0}\"", result);
						}
						else
						{
							result = string.Format("rel=\"nofollow\" href=\"{0}\"", result);
						}
					}
					catch
					{
					}
				}
			}
			else
			{
				result = "href=\"\"";
			}

			return result;
		}

		static string GetIdAttributeValue(IAttributeRenderingContext attributeRenderingContext)
		{
			if (!string.IsNullOrWhiteSpace(attributeRenderingContext.AttributeValue))
				return " id=\"" + attributeRenderingContext.AttributeValue + "\"";

			return string.Empty;
		}

		static string GetClassAttributeValue(IAttributeRenderingContext attributeRenderingContext)
		{
			if (!string.IsNullOrWhiteSpace(attributeRenderingContext.AttributeValue))
				return " class=\"" + attributeRenderingContext.AttributeValue + "\"";

			return string.Empty;
		}

	}
}